package com.tte.common.anno.DictConver;

import com.tte.common.model.po.Dictionary;
import com.tte.common.service.DictionaryService;
import lombok.SneakyThrows;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 字典表转换工具类
 */
@Component
public class DictUtils {

    private static DictionaryService dictionaryService;

    @Autowired
    public DictUtils(DictionaryService inDictionaryService){
        dictionaryService = inDictionaryService;
    }


    private static final String DICT_FIELD_SUFFIX = "Text";

    public static void convertDict(Object target) {
        if (target == null){
            return;
        }
        if (target instanceof List) {
            List<?> objectList = ((List<?>) target);
            if (CollectionUtils.isNotEmpty(objectList)) {
                List<String> dictTypes = getDictType(objectList);
                if (CollectionUtils.isEmpty(dictTypes)){
                    return;
                }
                List<Dictionary> dictionaryList = dictionaryService.getByTypes(dictTypes);
                Map<String, Map<String, String>> dictMapMap = dictionaryList.stream().collect(
                        Collectors.groupingBy(Dictionary::getcClass, Collectors.toMap(Dictionary::getcCode, Dictionary::getcValue)));

                if (CollectionUtils.isEmpty(dictionaryList)) {
                    return;
                }
                objectList.forEach(t -> doConvertDict(t, dictMapMap));
            }
        } else {
            List<String> dictTypes = getDictType(target);
            if (CollectionUtils.isEmpty(dictTypes)){
                return;
            }
            List<Dictionary> dictionaryList = dictionaryService.getByTypes(dictTypes);
            Map<String, Map<String, String>> dictMapMap = dictionaryList.stream().collect(
                    Collectors.groupingBy(Dictionary::getcClass, Collectors.toMap(Dictionary::getcCode, Dictionary::getcValue)));
            if (CollectionUtils.isEmpty(dictionaryList)) {
                return;
            }
            doConvertDict(target, dictMapMap);
        }
    }

    public static List<String> getDictType(List<?> objectList) {
        List<String> dictTypes = new ArrayList<>();
        for (Object object : objectList){
            List<String> types = getDictType(object);
            if (CollectionUtils.isNotEmpty(types)){
                dictTypes.addAll(types);
            }
        }
        if (CollectionUtils.isNotEmpty(dictTypes)){
            return dictTypes.stream().distinct().collect(Collectors.toList());
        }
        return null;
    }
    public static List<String> getDictType(Object object) {
        List<String> dictTypes = new ArrayList<>();
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            boolean containFormatField = field.isAnnotationPresent(DictConver.class);
            if (containFormatField) {
                //获取访问权
                field.setAccessible(true);
                DictConver dictConver = field.getAnnotation(DictConver.class);
                String dictType = dictConver.dictName();
                if (StringUtils.isNotBlank(dictType)){
                    dictTypes.add(dictType);
                }
            }
        }
        return dictTypes;
    }

    @SneakyThrows
    private static void doConvertDict(Object target, Map<String,Map<String,String>> dictMapType) {

        Field[] fields = target.getClass().getDeclaredFields();
        for (Field field : fields) {
            boolean containFormatField = field.isAnnotationPresent(DictConver.class);
            if (containFormatField) {
                //获取访问权
                field.setAccessible(true);
                String dictTypeStr = Objects.toString(field.get(target));
                if (StringUtils.isBlank(dictTypeStr)){
                    return;
                }

                DictConver dictConver = field.getAnnotation(DictConver.class);
                String dictType = dictConver.dictName();
                if (StringUtils.isBlank(dictType)){
                    continue;
                }

                Map<String,String> dictMap = dictMapType.get(dictType);
                String dictField = field.getName() + DICT_FIELD_SUFFIX;

                //判断fields中是否getName()为dictField的
                Field targetField = Arrays.stream(fields).filter(f -> StringUtils.equals(f.getName(), dictField)).findFirst().orElse(null);
                if (targetField != null && targetField.getType().equals(String.class)){
                    targetField.setAccessible(true);
                    targetField.set(target, dictMap.get(dictTypeStr));
                }

            }
        }
    }

}
